/* 
 * Copyright [2018] [Alex/libo(liboware@gmail.com)]
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.aop.handler.cglib;

import com.hyts.aop.base.BaseAopHandler;
import com.hyts.aop.error.AopException;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;

/** 
 * @author LiBo/Alex
 * @see com.hyts.aop.base.BaseAopHandler
 * @since V1.0
 * @version V1.0 
 */
public class CglibAopHandler extends BaseAopHandler {

    /**  
     * @fieldName enhancer
     * @fieldType Enhancer
     */ 
    private final Enhancer enhancer;

    /**
     * aop 处理器操作
     * @param proxyRealObject
     * @param callBack
     */
    public CglibAopHandler(Object proxyRealObject,Callback callBack){
        super(proxyRealObject);
        enhancer = new Enhancer();
        enhancer.setSuperclass(proxyRealObject.getClass());
        enhancer.setCallback(callBack);
    }

    /**  
     * @constructor：CglibAopHandler  
     * @param proxyRealObject  
     */ 
    public CglibAopHandler(Object proxyRealObject) {
        super(proxyRealObject);
        enhancer = new Enhancer();
        enhancer.setSuperclass(proxyRealObject.getClass());
        enhancer.setCallback(new MethodInterceptorHandler(proxyRealObject));
    }

    /**
     * @param proxyRealObject
     * @param weaveObject
     */
    public CglibAopHandler(Object proxyRealObject,Object... weaveObject) {
        super(proxyRealObject);
        enhancer = new Enhancer();
        enhancer.setSuperclass(proxyRealObject.getClass());
        enhancer.setCallback(new MethodInterceptorHandler(proxyRealObject,weaveObject));
    }
    
    /**  
     * @name enhancer's getter method
     * @return enhancer
     */
    public Enhancer getEnhancer() {
        return enhancer;
    }

    /* 
     * @param clazz
     * @return
     * @throws AopException
     * @see com.hyts.aop.base.BaseAopHandler#build(java.lang.Object)  
     * @exception
     */ 
    @SuppressWarnings("unchecked")
    @Override
    public <T> T build(T clazz) throws AopException {
        return (T) enhancer.create();
    }

    /* 
     * @return
     * @throws AopException
     * @see com.hyts.aop.base.BaseAopHandler#build()  
     * @exception
     */ 
    @Override
    public Object build() throws AopException {
        return enhancer.create();
    }

    public static void main(String[] args){
        Object object = new Object();
        CglibAopHandler cglibAopHandler = new CglibAopHandler(object,new FixedValue() {
            @Override
            public Object loadObject() throws Exception {
                return "Hello cglib";
            }
        });
    }
    
}
